package dk.hewison.util;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;


/* * Created on Jun 9, 2007 */

public class TestIIOthumbnails {

    private final static String[] knownFormats;

    static {
        knownFormats = ImageIO.getReaderFormatNames();
        for (int x = 0; x < knownFormats.length; x++) {
            knownFormats[x] = '.' + knownFormats[x].toLowerCase();
        }
    }

    public static void main(String[] args) {
        int thumbnailDimension = 300;
        float thumbnailQuality = 0.5f;

        long start = System.currentTimeMillis();
        try {

            //String[] fileNames = {"PIA03231.JPG", "PIA03241.JPG", "PIA08814.JPG", "PIA09201.JPG", "PIA09202.JPG", "PIA09203.JPG", "PIA09205.JPG", "PIA09207.JPG", "PIA09259.JPG", "large4.png", "large3.png", "large2.png", "large.png", "marbles.tif", "xing_t24.tif"};
            String[] fileNames = {
                    "/Users/johnhewison/dev/gwt_apps/MyMedia/src/dk/hewison/public/user/2005/12/jul/julepiger.jpg",
                    "/Users/johnhewison/dev/gwt_apps/MyMedia/src/dk/hewison/public/user/2005/12/jul/julepiger02.jpg"
            };

            for (int x = 0; x < fileNames.length; x++) {
                final File inputFile = new File(fileNames[x]);
                if (!inputFile.exists()) {
                    Log.debug("Unable to locate file: " + inputFile.getCanonicalPath());
                    continue;
                }

                final File thumbnailFile = makeThumbnailFile(inputFile, thumbnailDimension, thumbnailQuality);
                if (thumbnailFile != null && thumbnailFile.exists()) {
                    Log.debug(thumbnailFile.getCanonicalPath() + " succesfully created");
                } else {
                    Log.debug("Unable to create thumbnail for " + inputFile.getCanonicalPath());
                }
            }
            long stop = System.currentTimeMillis();
            Log.debug("Done. " + (stop - start));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static File makeThumbnailFile(File inputFile, int thumbnailDimension, float thumbnailQuality) {

        File response = null;

        try {
            if (inputFile == null) {
                Log.debug("Input file is null");
                return response;
            }
            if (!inputFile.exists()) {
                Log.debug("Input file does not exist: " + inputFile.getName());
                return response;
            }
            if (!isKnownFormat(inputFile.toString())) {
                Log.debug("Unsupported file format: " + inputFile.getName());
                return response;
            }


            final String fileSuffix = knownAliases(inputFile.getName()).substring(1);

            final ImageReader imgReader = (ImageReader) ImageIO.getImageReadersBySuffix(fileSuffix).next();

            final ImageInputStream bufferedInput = ImageIO.createImageInputStream(new BufferedInputStream(new FileInputStream(inputFile)));

            imgReader.setInput(bufferedInput);

            int imgHeight = imgReader.getHeight(0);
            int imgWidth = imgReader.getWidth(0);

            double imageRatio = (double) imgWidth / (double) imgHeight;
            int thumbnailHeight = thumbnailDimension;
            int thumbnailWidth = thumbnailDimension;

            if (imageRatio > 1.0d) {
                thumbnailHeight = (int) (thumbnailDimension / imageRatio);
            } else {
                thumbnailWidth = (int) (thumbnailDimension * imageRatio);
            }

            int longEdge = (Math.max(imgHeight, imgWidth));
            int tempThumbnailEdge = (int) ((float) thumbnailDimension * 1.25f);
            int subSample = (int) ((float) longEdge / (float) tempThumbnailEdge);

            final ImageReadParam readParam = imgReader.getDefaultReadParam();
            if (subSample > 1) {
                readParam.setSourceSubsampling(subSample, subSample, 0, 0);
            }

            final BufferedImage tempThumbnailImage = imgReader.read(0, readParam);

            final Frame frame = new Frame();
            frame.addNotify();
            final BufferedImage thumbnailImage = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
            final Graphics2D graphics2D = thumbnailImage.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.drawImage(tempThumbnailImage, 0, 0, thumbnailWidth, thumbnailHeight, frame);

            final String thumbnailFileName = inputFile.getParent() + "/" + "zz" + inputFile.getName();
            final File thumbnailFile = new File(thumbnailFileName);
            final BufferedOutputStream thumbnailOut = new BufferedOutputStream((new FileOutputStream(thumbnailFile)), 4092);
            final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(thumbnailOut);
            final JPEGEncodeParam encoderParam = encoder.getDefaultJPEGEncodeParam(thumbnailImage);
            encoderParam.setQuality(thumbnailQuality, false);
            encoder.setJPEGEncodeParam(encoderParam);
            encoder.encode(thumbnailImage);
            thumbnailOut.close();

// Dispose of AWT components graphics2D.dispose(); frame.dispose();

            response = thumbnailFile;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    private static boolean isKnownFormat(String fileName) {
        boolean response = false;

        if (fileName == null || fileName.length() == 0) {
            return response;
        }
        int extensionPosition = fileName.lastIndexOf('.');

        if (extensionPosition == -1) return response;

        final String extension = knownAliases(fileName.substring(extensionPosition).toLowerCase());

        for (int x = 0; x < knownFormats.length; x++) {
            if (extension.equals(knownFormats[x])) {
                return true;
            }
        }

        return response;
    }

    private static String knownAliases(String fileName) {
        final String extension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
        if (extension.equals(".jpg")) return ".jpeg";
        if (extension.equals(".jpe")) return ".jpeg";
        if (extension.equals(".tif")) return ".tiff";
        return extension;
    }

    private static String getThumbnailFileName(String attachmentName) {
        String result = null;
        int dotIndex = 0;

// Get the position of the . before the extension dotIndex = attachmentName.lastIndexOf( "." ); // Get the extension of the current file final String extension = attachmentName.substring( dotIndex + 1 ); // Get the file name without the extension result = attachmentName.substring( 0 , dotIndex ); // Build the thumbnail file name result = result + "_thumb_" + extension + ".jpg";

        return result;
    }
}